/** QC/TODO Pending  - chk cleanup
 * 27-Mar-2011 Created
 * 02-Apr-2011 Deal with potential JSON trojans/spoofs on indempotent request - log in as A delete/edits B's data
 *             Refactor to use sub resource approach
 */
package com.munoor.dalai.server.api;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import com.munoor.dalai.server.model.EMFService;
import com.munoor.dalai.server.model.Filter;
import com.munoor.dalai.server.model.wrappers.WrappedFilter;
import com.munoor.dalai.server.model.wrappers.WrappedFilterList;
import com.sun.jersey.api.NotFoundException;

/**
 * @author Osho Ilamah
 * @since version 1.0 (27 March 2011)
 */
@Path("users/{userId}/filters")
public class FiltersService {
	@Context
	UriInfo uriInfo;
	@Context
	Request request;

	@SuppressWarnings("unchecked")
	@GET
	@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
	public WrappedFilterList getFilters(@PathParam("userId") Long userId, @QueryParam("start") @DefaultValue("0") int start, @QueryParam("items") @DefaultValue("10") int items) {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			List<Filter> filterObjects = em.createNamedQuery("Filters.findByUserId").setParameter("userId", userId).setFirstResult(start).setMaxResults(items).getResultList();
			List<WrappedFilter> filterWrappers = new ArrayList<WrappedFilter>();
			for (Filter f : filterObjects) {
				filterWrappers.add(new WrappedFilter(f));
			}
			int existingCount = ((Integer) em.createNamedQuery("Filters.getFilterCountByUserId").setParameter("userId", userId).getSingleResult()).intValue();

			int nextStart = existingCount > (start + items) ? (start + items) : 0;
			int prevStart = (start - items) > 0 ? (start - items) : 0;
			String next = "";
			if (nextStart > 0) {
				next = "start=" + nextStart + "&items=" + items;
			}
			WrappedFilterList wrappedFiltersList = new WrappedFilterList(filterWrappers, next, "start=" + prevStart + "&items=" + items, start, filterObjects.size(), existingCount);
			return wrappedFiltersList;
		} catch (Exception e) {
			throw new NotFoundException("Not Found");
		} finally {
			em.close();
		}
	}

	@POST
	@Consumes({ MediaType.APPLICATION_JSON })
	public Response createFilter(WrappedFilter postData, @PathParam("userId") Long userId) {
		EntityManager em = EMFService.get().createEntityManager();
		EntityTransaction txn = em.getTransaction();
		try {
			Filter filter = postData.unmarshall();
			// enforce Trojan User /spoof block
			filter.setUserId(userId);
			txn.begin();
			em.persist(filter);
			txn.commit();
			return Response.created(uriInfo.getAbsolutePathBuilder().path("" + filter.getFilterId()).build()).build();
		} catch (Exception e) {
			return Response.serverError().build();
		} finally {
			em.close();
		}
	}

	@DELETE
	public Response deleteFilters(String ids) {
		String[] strIds = ids.split("\\s"); // space delimited ids e.g. 53 54 57
		EntityManager em = EMFService.get().createEntityManager();
		try {
			Filter filter;
			for (String id : strIds) {
				filter = (Filter) em.createNamedQuery("Filters.findByFilterId").setParameter("filterId", Long.parseLong(id)).getSingleResult();
				// enforce Trojan User /spoof block
				if (uriInfo.getPath().indexOf("users/" + filter.getUserId() + "/") != -1) {
					// only delete a filter if it is owned by logged in user
					em.remove(filter);
				}
			}
			return Response.noContent().build();
		} catch (Exception e) {
			throw new NotFoundException("Not Found");
		} finally {
			em.close();
		}
	}

	// SUB-RESOURCE CALLS
	// methods, etc to be handled by sub-resource

	@Path("{filterId}")
	// = users/{userId}/filters/{filterId}
	public FilterResource getFilter(@PathParam("filterId") Long filterId) {
		return new FilterResource(uriInfo, request, filterId);
	}
}
